#!/usr/bin/env python

import logging
import os
import shutil
import gzip
import time
import hashlib

from executionhelper import safe_exec
from config import split_strip

def store_dict(fname, d):
	with open(fname, 'w') as f:
		f.write(repr(d))

def read_dict(fname):
	ret = None
	with open(fname, 'r') as f:
		ret = eval(f.read())
	return ret

def create_archive(log, config, env):
	archive = config.get('directories','dumps')+'/mobiemu_config_archive.tar.gz'
	include = config.get('source_archiver','include')
	
	if config.getboolean('source_archiver', 'include_config'):
		include += ' {}'.format(config.get('source_archiver', 'config_file'))
	
	for backup in include.split(' '):
		backup = backup.strip()
		if not os.path.exists(backup):
			log.warning('Could not find file %s when creating backup, this file will be ignored!', backup)
			include = include.replace(backup, '')

	log.info("Archiving configuration files in {}...".format(archive).strip())

	command ="tar --preserve-order cvzf " + archive + " `find " + include + " | sort --stable`"
	safe_exec(['tar','cvzf',archive,include], log, config, env, use_shell=True,chdir=False)

	return archive

def md5_file(filename):
	try:
		f = gzip.open(filename)
		md5 = hashlib.md5()
		while True:
			data = f.read(8192)
			if not data:
				break
			md5.update(data)
	finally:
		f.close()
	return md5.hexdigest()

def get_date_string():
	ds = str(time.ctime())
	ds = ds.replace(' ','_')
	ds = ds.replace(':','')
	ds = ds.replace('/','')
	return ds

def move_results(log, config, env, directory_tag=None):
	log.info("Moving results to archive directory")
	archive = create_archive(log, config, env)
	log.info("Calculating source checksum...")
	checksum = md5_file(archive)
	log.info("Checksum: {}".format(checksum))
	archive_md5 = '_'.join(split_strip(',',config.get('general','experiments'))) + "_" + config.get('general','topology') + "_" + checksum
	

	# move results in to the following directory structure
	# results/md5 of source archive/directory_tag

	results_base_dir = config.get('directories','results')
	if not os.path.exists(results_base_dir):
		raise Exception("Results directory ({}) doesn't exist.".format(results_base_dir))

	results_dir = results_base_dir + "/" + archive_md5
	if not os.path.exists(results_dir):
		log.info("Results directory for this source checksum not found, creating...")
		os.mkdir(results_dir)
		shutil.move(archive,results_dir)

	if directory_tag == None:
		directory_tag = get_date_string()
	else:
		directory_tag = directory_tag + "_" + get_date_string()

	target_dir = results_dir + "/" + directory_tag
	
	if os.path.exists(target_dir):
		raise Exception("target directory already exists ({}). Aborting...".format(target_dir))

	os.mkdir(target_dir)

	include = config.get('results_archiver','include')
	try:
		safe_exec(['mv','-v',include,target_dir], log, config, env, use_shell=True, chdir=False)
	except:
		log.error("Unable to move results to " + target_dir)
		raise

	log.info("results moved from {} to {}".format(include,target_dir))